package Donnees;

import Metier.Objets.Produit;
import Metier.Objets.Stock;
import Metier.Objets.TypeProduit;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class DaoProduit {

    /**
     * Ajoute un produit en base de données avec ses paramètres
     * @param produit  objet Produit
     * @throws SQLException 
     */
    public void ajouter(Produit produit) throws SQLException{
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        try{
            int est_boisson = 0;
            
            //Récupération de la connexion
            connection = ConnectionFactory.getConnection();
            
            //Déclaration de la requête
            String query = "INSERT INTO PRODUIT (libelle, est_boisson, "
                    + "prix_unitaire, duree_vie, temps_cuisson, seuil_stock, "
                    + "seuil_heure_creuse, seuil_heure_pleine)"
                    + " VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
            
            if(produit.getType() == TypeProduit.BOISSON){
                est_boisson = 1;
            }
            
            //Préparation de la requête
            preparedStatement = connection.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);
            preparedStatement.setString(1, produit.getNom());
            preparedStatement.setInt(2, est_boisson);
            preparedStatement.setFloat(3, produit.getPrix());
            preparedStatement.setInt(4, produit.getDureeVie());
            preparedStatement.setInt(5, produit.getTempsCuisson());
            preparedStatement.setInt(6, produit.getSeuilStock());
            preparedStatement.setInt(7, produit.getSeuilVitrine());
            preparedStatement.setInt(8, produit.getSeuilVitrineHDP());
            
            //Exécution de la requête
            preparedStatement.executeUpdate();
            ResultSet rs = preparedStatement.getGeneratedKeys();
            rs.next();
            int key = rs.getInt(1);
            produit.setId(key);
            
            if(est_boisson == 0){
                new DaoStock().ajouter(new Stock(-1, key));
            }
        }
        finally{
            DbUtil.close(preparedStatement);
            DbUtil.close(connection);
        }
    }

    /**
     * Renvoie le produit avec l'id id
     * @param id id du produit à rechercher
     * @return produit d'id id
     * @throws java.sql.SQLException
     */
    public Produit chercher(int id) throws SQLException {
        return this.chercher("WHERE id=" + id).get(0);
    }

    /**
     * Renvoie la liste de tout les produits
     * @return Liste des produits
     * @throws SQLException
     */
    public List<Produit> chercher() throws SQLException{
        return this.chercher("");
    }
    
    /**
     * Renvoie la liste des produits dont le nom correspond à peu près à celui passé en paramètre
     * @param nom le nom en question
     * @return Liste des produits
     * @throws SQLException
     */
    public List<Produit> chercherLibelleApprox(String nom) throws SQLException{
        return this.chercher("WHERE libelle LIKE '"+nom+"'");
    }
    
    /**
     * Renvoie la liste des produits selon la clause where
     * @param whereClause Clause where de la requete sql
     * @return La liste des produits de type type
     * @throws SQLException
     */
    private List<Produit> chercher(String whereClause) throws SQLException{
        Connection connection = null;
        Statement statement = null;
        String query = "SELECT * FROM PRODUIT " + whereClause;
        TypeProduit tp;
        ResultSet rs = null;
        List<Produit> list = new ArrayList<>();
        try {
            connection = ConnectionFactory.getConnection();
            statement = connection.createStatement();
            rs = statement.executeQuery(query);
            while (rs.next()) {
                if (rs.getBoolean("est_boisson"))
                    tp = TypeProduit.BOISSON;
                else
                    tp = TypeProduit.VIENNOISERIE;    
                list.add(new Produit(rs.getInt("id"),
                    rs.getString("libelle"),
                    tp,
                    rs.getFloat("prix_unitaire"),
                    rs.getInt("seuil_stock"),
                    rs.getInt("seuil_heure_creuse"),
                    rs.getInt("seuil_heure_pleine"),
                    rs.getInt("temps_cuisson"),
                    rs.getInt("duree_vie")));
            }
        } finally {
            DbUtil.close(rs);
            DbUtil.close(statement);
            DbUtil.close(connection);
        }
        
        //Tri de la liste de produit par type de produit
        Collections.sort(list);
        return list;
    }
    
    /**
     * Renvoie la liste des viennoiseries
     * @return Liste de viennoiseries
     * @throws SQLException
     */
    public List<Produit> chercherViennoiseries() throws SQLException {
        return this.chercher("WHERE NOT est_boisson");
    }

    /**
     * Renvoie la liste des boissons
     * @return Liste de boissons
     * @throws SQLException
     */
    public List<Produit> chercherBoissons() throws SQLException {
        return this.chercher("WHERE est_boisson");
    }
    
    /**
     * Modifie le produit renseigné en base de données.
     * @param produit  produit à modifier
     * @throws SQLException 
     */
    public void modifier(Produit produit) throws SQLException{
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        try{
            int est_boisson = 0;
            
            //Récupération de la connexion
            connection = ConnectionFactory.getConnection();
            
            //Déclaration de la requête
            String query = "UPDATE PRODUIT SET libelle = ?, est_boisson = ?, prix_unitaire = ?, duree_vie = ?, temps_cuisson = ?, seuil_stock = ?, seuil_heure_creuse = ?, seuil_heure_pleine = ?" 
                            + " where id = ?";
            
            if(produit.getType() == TypeProduit.BOISSON){
                est_boisson = 1;
            }
            
            //Préparation de la requête
            preparedStatement = connection.prepareStatement(query);
            preparedStatement.setString(1, produit.getNom());
            preparedStatement.setInt(2, est_boisson);
            preparedStatement.setFloat(3, produit.getPrix());
            preparedStatement.setInt(4, produit.getDureeVie());
            preparedStatement.setInt(5, produit.getTempsCuisson());
            preparedStatement.setInt(6, produit.getSeuilStock());
            preparedStatement.setInt(7, produit.getSeuilVitrine());
            preparedStatement.setInt(8, produit.getSeuilVitrineHDP());
            preparedStatement.setInt(9, produit.getId());
            
            //Exécution de la requête
            preparedStatement.executeUpdate();
        }
        finally{
            DbUtil.close(preparedStatement);
            DbUtil.close(connection);
        }
    }
    
    /**
     * Supprime le produit associé à l'identifiant passé en paramètre
     * @param id  identifiant du produit à supprimer
     * @throws SQLException 
     */
    public void supprimer(int id) throws SQLException{
        Connection connection = null;
        Statement statement = null;
        try {

            String query = "DELETE FROM PRODUIT where id=" + id;
            connection = ConnectionFactory.getConnection();
            statement = connection.createStatement();
            statement.execute(query);
        } finally {
            DbUtil.close(statement);
            DbUtil.close(connection);
        }
    }
}
